#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>

#include "StdTcp.h"

struct TcpServer
{
    int sock;

};

TcpS *InitTcpServer(const char *ip, short int port)
{
    TcpS *s=(TcpS *)malloc(sizeof(TcpS));
    if(s==NULL)
    {
        printf("inittcpserver malloc error\n");
        return NULL;
    }
    s->sock=socket(AF_INET,SOCK_STREAM,0);
    if(s->sock==-1)
    {
        perror("socket");
        free(s);
        return NULL;
    }
    int isuse=1;
    if(setsockopt(s->sock,SOL_SOCKET,SO_REUSEADDR,&isuse,4)!=0)
    {
        perror("setsockopt");
        free(s);
        return NULL;
    }
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    addr.sin_addr.s_addr=inet_addr(ip);
    if(bind(s->sock,(struct sockaddr*)&addr,sizeof(addr))!=0)
    {
        perror("bind");
        free(s);
        return NULL;
    }
    if(listen(s->sock,10)!=0)
    {
        perror("listen");
        free(s);
        return NULL;
    };
    return s;
}

int TcpServerAccept(TcpS *s)
{
    struct sockaddr_in clinetaddr;
    socklen_t len;
    int acceptsock=accept(s->sock,(struct sockaddr*)&clinetaddr,&len);
    if(acceptsock==-1)
    {
        perror("accept");
        return -1;
    }
    return acceptsock;
}

void TcpServerSend(int clinetsock, void *ptr, size_t size)
{
    if(send(clinetsock,ptr,size,0)<0)
    {
        perror("TcpServerSend");
        return;
    }
}

void TcpServerRecv(int clinetsock, void *ptr, size_t size)
{
    if(recv(clinetsock,ptr,size,0)<0)
    {
        perror("TcpServerRecv");
        return;
    }
}

void CloseTcpServer(TcpS *s)
{
    close(s->sock);
    free(s);
    
}

struct TcpClinet
{
    int sock;
    

};

TcpC *InitTcpClinet(const char *serverip, short int serverport)
{
    TcpC *c=(TcpC *)malloc(sizeof(TcpC));
    if(c==NULL)
    {
        printf("inittcpclinet malloc error\n");
        return NULL;
    }
    c->sock=socket(AF_INET,SOCK_STREAM,0);
    if(c->sock==-1)
    {
        perror("socket");
        free(c);
        return NULL;
    }
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(serverport);
    addr.sin_addr.s_addr=inet_addr(serverip);
    if(connect(c->sock,(struct sockaddr*)&addr,sizeof(addr))!=0)
    {
        perror("connect");
        free(c);
        return NULL;
    }
    return c;
}

void TcpClinetSend(TcpC *c, void *ptr, size_t size)
{
    if(send(c->sock,ptr,size,0)<0)
    {
        perror("TcpClinetSend");
    }
}

void TcpClinetRecv(TcpC *c, void *ptr, size_t size)
{
    if(recv(c->sock,ptr,size,0)<0)
    {
        // perror("TcpClinetrecv");
        return;
    }
}

void CloseTcpClinet(TcpC *c)
{
    close(c->sock);
    free(c);
}